<?php

namespace App\Service\Exam;

use App\Dao\Exam\ExamDao;
use App\Dao\Question\QuestionDetailDao;
use App\Dao\User\UserDao;
use App\Event\Ocean\OceanQuestion;
use App\Model\Exam\ExamQuestion;
use App\Model\Exam\ExamTest;
use App\Model\Exam\ExamTestResult;
use App\Model\Question\QuestionDesc;
use App\Model\Question\QuestionDescCharacterItem;
use App\Service\BaseService;
use App\Tool\Collect;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Str;
use Yj\Apidog\Annotation\PostApi;

class ExamService extends BaseService
{
    /**
     * @Inject()
     * @var ExamDao
     */
    protected $examDao;

    /**
     * @Inject()
     * @var ExamQuestion
     */
    protected $examQuestion;

    /**
     * @Inject()
     * @var QuestionDetailDao
     */
    protected $questionDetailDao;


    /**
     * @Inject()
     * @var ExamTest
     */
    protected $examTest;

    /**
     * @Inject()
     * @var ExamTestResult
     */
    protected $examTestResult;

    public function lists()
    {
        $data = $this->examDao->orderByDesc('id')->getList();
        return ($data);
    }

    public function question(int $exam_id)
    {

        $data = $this->examDao->DaoWhere(compact('exam_id'))->with(['Question' => function ($query) {
            $query->with('QuestionDetail');
        }])->firstOr(function () {
            _Error('不存在该考试');
        });

        $data->Question->transform(function ($question) {
            $question->QuestionDetail->transform(function ($questionDetail, $index) {
                $questionDetail->option = Str::upper(chr($index + 97));
                return $questionDetail;
            });
            return $question;
        });
        return $data;
    }

    public function edit($id, $data)
    {
        $examDao = $this->examDao->DaoWhere(compact('id'))->firstOr(function () {
            _Error('不存在该考试');
        });

        $examDao->fill($data->toArray());
        $examDao->save();
        return true;
    }

    public function del(int $id)
    {
        $examDao = $this->examDao->DaoWhere(compact('id'))->firstOr(function () {
            _Error('不存在该考试');
        });
        $examDao->delete();
        return true;
    }

    public function add(\App\Tool\Collect $data)
    {
        $this->examDao->create($data->toArray());
        return true;
    }

    public function join(\App\Tool\Collect $data)
    {

    }

    public function detail($examTestId)
    {

        $exam = $this->examDao->whereIn('id', [1, 2, 3, 4, 5])->withCount('Question')->get();
        $examTest = $this->examTest->where('id', $examTestId)->first();
        $data['detail'] = $examTest;
        $data['exam'] = $exam;
        $exam->transform(function ($data) use ($examTestId) {
//            $examTestResult->Exam->time * 60;

            $examTestResult = $this->examTestResult->where('subject_id', $data->id)->where('exam_test_id', $examTestId)->first();

            $data->status = $this->getStatus($examTestResult, $data->time);

            $data->examTestResult = $examTestResult;
            return $data;
        });
        //$examDao =  $this->examDao->where('id',$id)->first();
//        $questionSum = $this->examQuestion->where('exam_id',1)->count();
//        $examDao->question_sum = $questionSum;
        return $data;
    }

    public function start($exam_test_id, $exam_id)
    {
//        dd($exam_test_id,$exam_id);
//        $this->isTest($exam_test_id,$exam_id) && _Error('已经考试了');
        return $this->examTestResult->firstOrCreate([
            'subject_id' => $exam_id,
            'exam_test_id' => $exam_test_id
        ], ['start_time' => time()]);

//        $examDao = $this->examDao->where('id',$id)->first();
//        if($examDao->start_time>0){
////            _Error('考试已经开始了');
//        }
//        $examDao->start_time = time();
//        return $examDao->save();
    }

    /**
     * @Inject()
     * @var UserDao
     */
    protected $userDao;

    public function result(Collect $data)
    {
        $user_id = $data->get('user_id');

        //判断今日是否答题
        if ($this->examTestResult
            ->where('user_id', $user_id)
            ->yjRangeTime('create_time', 'today')
            ->exists()) {
            _Error('明日再来吧！');
        }
        $data->offsetSet('result', json_encode($data->get('result')));
        $this->examTestResult->create($data->toArray());
        $beans = systemConfig('exam_beans');

        $this->userDao->opAccount('integral', $user_id, $beans, 'exam', 0);
        event()->dispatch(new OceanQuestion($data->get('user_id')));
        return true;
        //删除
//        $this->isTest($exam_test_id,$subject_id) && _Error('已经考试了');
//        return $this->examTestResult->create([
//            'result'=>json_encode($result),
//            'submit_time'=>time(),
//            'subject_id'=>$subject_id,
//            'exam_test_id'=>$exam_test_id
//        ]);
    }

    public function isTest($exam_test_id, $subject_id)
    {
        $examTestResult = $this->examTestResult->with('Exam')
            ->where('exam_test_id', $exam_test_id)
            ->where('subject_id', $subject_id)
            ->first();


        return $examTestResult;
    }

    /**
     * @Inject()
     * @var QuestionDesc
     */
    protected $questionDesc;

    /**
     * @Inject()
     * @var QuestionDescCharacterItem
     */
    protected $questionDescCharacterItem;

    public function report($exam_test_id)
    {
        $examTest = $this->examTest->with(['ExamTestResult' => function ($query) {
            $query->orderBy('subject_id');
        }])->where('id', $exam_test_id)->first();

        $report = collect(
            [
                1 => [
                    'A',
                    'C',
                    'E',
                    'I',
                    'R',
                    'S'
                ],
                2 => [
                    '外向' => 'E',
                    '内向' => 'I',
                    '感觉' => 'S',
                    '直觉' => 'N',
                    '思考' => 'T',
                    '情感' => 'F',
                    '判断' => 'J',
                    '知觉' => 'P',
                ],
                3 => [
                    "完美型",
                    "助人型",
                    "成就型",
                    "自我型",
                    "思智型",
                    "忠诚型",
                    "活跃型",
                    "领袖型",
                    "和平型",
                ],
                4 => [
                    '书写能力（C）',
                    '动手能力（O）',
                    '数学能力（M）',
                    '社会交往能力（L）',
                    '空间判断能力（I）',
                    '组织管理能力（U）',
                    '观察细节能力（S）',
                    '言语能力（T）',
                    '运动协调能力（D）',
                ], 5 => [
                'TF（技术职能型）',
                'GM（管理型）',
                'AU（自主独立型）',
                'SE（安全稳定型）',
                'EC（创造创业型）',
                'SV（服务奉献型）',
                'CH（挑战型）',
                'LS（生活型）',
            ]]);

        $examTest->examTestResult->transform(function ($item) use ($report) {
            $subject_id = $item->subject_id;
            $sonReport = $report->get($item->subject_id);
            $result = json_decode($item->result, true) ?: [];
            if ($subject_id == 2) {

                $item->score = collect($sonReport)->transform(function ($types) use ($result) {
                    return (int)($this->questionDetailDao->whereIn('id', $result)->where('types', $types)->sum('score') ?: 0);
                })->values();

                $chartData = [0 => ['外形', '内向'], 1 => ['感觉', '直觉'], 2 => ['思考', '情感'], 3 => ['判断', '知觉']];

                $score = ($item->score);

                $chartData = collect($chartData)->transform(function ($item, $key) use ($result, $score) {
                    return [
                        'series' => [
                            [
                                "data" => [
                                    [
                                        'name' => $item[0],
                                        'value' => $score[(2 * $key)],
                                    ],
                                    [
                                        'name' => $item[1],
                                        'value' => $score[(2 * $key) + 1],
                                    ]
                                ]
                            ]
                        ]
                    ];
                });

                $item->chartData = $chartData;
            } else {
                $item->score = collect($sonReport)->transform(function ($types) use ($result) {
                    return (int)($this->questionDetailDao->whereIn('id', $result)->where('types', $types)->sum('score') ?: 0);
                });
            }
            switch ($subject_id) {
                case 4:
                    $scoreResult = $item->score->sortByDesc(function ($value) {
                        return $value;
                    })->values();
                    break;
                case 2:
                    $scoreResult = [];
                    $score = $item->score;
                    $scoreResult[] = $score[0] >= $score[1] ? "E" : "I";
                    $scoreResult[] = $score[2] >= $score[3] ? "S" : "N";
                    $scoreResult[] = $score[4] >= $score[5] ? "T" : "F";
                    $scoreResult[] = $score[6] >= $score[7] ? "J" : "P";
                    break;
                default:
                    $scoreResult = $item->score->sortByDesc(function ($value) {
                        return $value;
                    })->slice(0, 3);
                    break;
            }

            $scoreResultTitle = [];

            if ($item->subject_id == 2) {
                $scoreResult = implode('', $scoreResult);
//                $desc = $this->questionDesc->with('QuestionDescItem')->where('title', $scoreResult)->first();
//                $item->scoreResultTitle = $scoreResult;
                $desc = Db::table('xg')->where('xf', $scoreResult)->first();

                $item->desc = $desc;
            } else {
                $scoreResult->transform(function ($item, $key) use ($sonReport, &$scoreResultTitle) {
                    $title = $sonReport[$key] ?? "";
                    $scoreResultTitle[] = $title;
                    $score = $item;
                    $desc = $this->questionDesc->with('QuestionDescItem')->where('title', $title)->first();
                    return compact('title', 'desc', 'score');
                });
                if ($subject_id == 4) {
                    $scoreResultTitle = array_slice($scoreResultTitle, 0, 3);
                    $item->scoreResultTitle = implode('+', $scoreResultTitle);
                } else {
                    $item->scoreResultTitle = implode('+', $scoreResultTitle);
                }
            }
            $item->scoreResult = $scoreResult;
            return $item;
        })->sortBy(function ($item) {
            return $item['subject_id'];
        })->values();
//
//        $examTest->exam_test_result = $examTest->exam_test_result->sortBy(function ($item) {
//            return $item->subject_id;
//        });
        $examTest = $examTest->toArray();
////        dd($examTest['exam_test_result']);
        $examTest['exam_test_result'] = collect($examTest['exam_test_result'])->sortBy(function ($item) {
            return $item['subject_id'];
        })->values();

        return $examTest;
    }

    private function getStatus($examTestResult, $time)
    {
        if ($examTestResult->submit_time > 0) {
            return 2;
        }
        if (empty($examTestResult)) {
            return 0;
        }
        if ($examTestResult->start_time + $time * 60 > time()) {
            return 1;
        }
        return 2;
    }

    public function today(mixed $user_id)
    {
        //判断今日是否答题
        $todayIsExam = $this->examTestResult
            ->where('user_id', $user_id)
            ->yjRangeTime('create_time', 'today')
            ->exists();

        $exam_beans = systemConfig('exam_beans');
        $exam_beans_max = $exam_beans + 5;
        return compact('todayIsExam', 'exam_beans', 'exam_beans_max');
    }

}